﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Services.Client;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using BuildARoute.BARDataService;
using BuildARoute.Bing.Route;
using Microsoft.Maps.MapControl;


namespace BuildARoute
{
    public partial class RouteWindow : ChildWindow, INotifyPropertyChanged
    {
       

        public RouteWindow()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(RouteWindow_Loaded);
        }

        void RouteWindow_Loaded(object sender, RoutedEventArgs e)
        {
            
            CurrentTour.POIs.LoadCompleted += new System.EventHandler<LoadCompletedEventArgs>(POIs_LoadCompleted);
            CurrentTour.POIs.LoadAsync();
            IsBusyIndicatorOn = true;

        }

        void POIs_LoadCompleted(object sender, LoadCompletedEventArgs e)
        {
            var entities = sender as DataServiceCollection<POI>;
            if (e.Error == null)
            {
                if (entities.Continuation != null)
                {
                    entities.LoadNextPartialSetAsync();
                }
                else
                {
                    drawRoute();
                    IsBusyIndicatorOn = false;
                }
            }
            else
            {
                MessageBox.Show(string.Format("Problem loading entities: {0}", entities.ToString()));
            }

        }

        private void drawRoute()
        {
            if (CurrentTour.POIs.Count > 1)
            {

                RouteServiceClient client = new RouteServiceClient("BasicHttpBinding_IRouteService");
                client.CalculateRouteCompleted += new System.EventHandler<CalculateRouteCompletedEventArgs>(client_CalculateRouteCompleted);

                //Calculate route request
                RouteRequest request = new RouteRequest();
                request.Credentials = new Credentials();
                request.Credentials.ApplicationId = MapInfo.ID;

                ObservableCollection<Waypoint> waypoints = new ObservableCollection<Waypoint>();
                foreach (var item in CurrentTour.POIs)
                {
                    var wp = new Waypoint();
                    wp.Location = new Location(item.Latitude, item.Longitude, 0, AltitudeReference.Ground);
                    waypoints.Add(wp);

                }
                request.Waypoints = waypoints;

                RouteOptions options = new RouteOptions();
                options.RoutePathType = RoutePathType.Points;
                request.Options = options;

                client.CalculateRouteAsync(request);

                setMapView();
            }
        }

        void client_CalculateRouteCompleted(object sender, CalculateRouteCompletedEventArgs e)
        {
            // If the route calculate was a success and contains a route, then draw the route on the map.
            if ((e.Result.ResponseSummary.StatusCode == ResponseStatusCode.Success) & (e.Result.Result.Legs.Count != 0))
            {
                // Set properties of the route line you want to draw.

                SolidColorBrush routeBrush = new SolidColorBrush(Colors.Blue);
                MapPolyline routeLine = new MapPolyline();
                routeLine.Locations = new LocationCollection();
                routeLine.Stroke = routeBrush;
                routeLine.Opacity = 0.65;
                routeLine.StrokeThickness = 5.0;

                // Retrieve the route points that define the shape of the route.
                foreach (Location p in e.Result.Result.RoutePath.Points)
                {
                    routeLine.Locations.Add(new Location(p.Latitude, p.Longitude, 0, AltitudeReference.Ground));
                }

                //Clean routeLayer
                routeLayer.Children.Clear();

                // Add the route line to the new layer.
                routeLayer.Visibility = Visibility.Visible;
                routeLayer.Children.Add(routeLine);

            }
        }

        private void setMapView()
        {
            if (CurrentTour.POIs.Count > 1)
            {
                var points = new List<Location>();
                foreach (var item in CurrentTour.POIs)
                {
                    points.Add(new Location(item.Latitude, item.Longitude, 0, AltitudeReference.Ground));
                }
                LocationRect locrect = new LocationRect(points);
                mapControl.SetView(locrect);
            }
        }



        #region fields and props
        

        private Tour _currentTour = null;

        /// <summary>
        /// Gets the CurrentTour property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public Tour CurrentTour
        {
            get
            {
                return _currentTour;
            }

            set
            {
                if (_currentTour == value)
                {
                    return;
                }

                _currentTour = value;

                // Update bindings, no broadcast
                RaisePropertyChanged("CurrentTour");
            }
        }

        public TourGuideSolutionDataEntities Context { get; set; }

        private Models.MapInfo _mapInfo = new Models.MapInfo();
        public Models.MapInfo MapInfo
        {
            get
            {
                return _mapInfo;
            }
            set
            {
                if (value == _mapInfo) return;
                _mapInfo = value;
                RaisePropertyChanged("MapInfo");
            }
        }

        private bool _isBusyIndicatorOn = false;
        public bool IsBusyIndicatorOn
        {
            get
            {
                return _isBusyIndicatorOn;
            }
            set
            {
                if (value == _isBusyIndicatorOn) return;
                _isBusyIndicatorOn = value;
                RaisePropertyChanged("IsBusyIndicatorOn");
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propName)
        {
            var propChanged = PropertyChanged;
            if (propChanged != null)
            {
                propChanged(this, new PropertyChangedEventArgs(propName));
            }
        }

        #endregion

        #region Map Logic

        #endregion

    }
}